//
//  File.swift
//  IDAPseudocodeOptimize
//
//  Created by marcow on 4/19/19.
//  Copyright © 2019 wgd. All rights reserved.
//

import Foundation

func testAll() {
    test_String_removeFirstblanks()
    test_String_replaceVars()
    test_String_fixBR()
    test_String_findRightParen()
    test_String_fix_objc_msgSend()
}

func test_String_removeFirstblanks() {
    var a = "  abc"
    if a.removeFirstblanks() != "abc" {
        fatalError()
    }
    a = "abc"
    if a.removeFirstblanks() != "abc" {
        fatalError()
    }
}

func test_String_replaceVars() {
    var a = " v14 = _objc_msgSend(&OBJC_CLASS___NSDictionary, \"dictionaryWithObjects:forKeys:count:\", &v16, &v166, v16);"
    var useValues = ["v14":["v14"], "v16":["v16", "value16"], "v166":["v166", "value166"]]
    var result = " v14 = _objc_msgSend(&OBJC_CLASS___NSDictionary, \"dictionaryWithObjects:forKeys:count:\", &value16, &value166, value16);"
    var new = a.replaceVars(with: useValues)
    
    if new != result  {fatalError() }
    
    a = "v4 = v3;"
    useValues = ["v4":["v4", "[MbModelTool, sharedInstance, a3]"], "v3":["v3", "[MbModelTool, sharedInstance, a3]"]]
    new = a.replaceVars(with: useValues)
//    if new != result  {fatalError() }
}

func test_String_fixBR() {
    let input = """
      v329 = _objc_msgSend(&OBJC_CLASS___NSBundle, "mainBundle");
      v330 = objc_retainAutoreleasedReturnValue(v329);
      lastTopicID = v330;
      v331 = (_objc_msgSend)(
               v330,
               "localizedStringForKey:value:table:",
               CFSTR("BookFileCrashAlertTitle"),
               &stru_101187420,
               0LL);
      title = objc_retainAutoreleasedReturnValue(v331);// ⬅️⬅️⬅️⬅️⬅️
      v332 = (_objc_msgSend)(&OBJC_CLASS___NSBundle, "mainBundle");
      v333 = objc_retainAutoreleasedReturnValue(v332);
      v482 = v333;
      v334 = (_objc_msgSend)(
               v333,
               "localizedStringForKey:value:table:",
               CFSTR("BookFileCrashAlertMsg"),
               &stru_101187420,
               0LL);
      v482 = v333;
"""
    
    let result =
"""
      v329 = _objc_msgSend(&OBJC_CLASS___NSBundle, "mainBundle");
      v330 = objc_retainAutoreleasedReturnValue(v329);
      lastTopicID = v330;
      v331 = (_objc_msgSend)(v330, "localizedStringForKey:value:table:", CFSTR("BookFileCrashAlertTitle"), &stru_101187420, 0LL);





      title = objc_retainAutoreleasedReturnValue(v331);// ⬅️⬅️⬅️⬅️⬅️
      v332 = (_objc_msgSend)(&OBJC_CLASS___NSBundle, "mainBundle");
      v333 = objc_retainAutoreleasedReturnValue(v332);
      v482 = v333;
      v334 = (_objc_msgSend)(v333, "localizedStringForKey:value:table:", CFSTR("BookFileCrashAlertMsg"), &stru_101187420, 0LL);





      v482 = v333;
"""
    if input.fixBR() != result { fatalError() }
    
    let input2 = """
      isAppRunning = lastBookMD5;
      if ( lastBookMD5
        && (v408 = _objc_msgSend(isAppRunning, "isEqualToString:", &stru_101187420), bookPath_v494___NSObject)
        && !v408 )
      {                                         // if (lastBookMD5 && lastBook && ![lastBookMD5 isEqualToString:@""])
        v409 = _objc_msgSend(self_v496, "rootController");
        v410 = objc_retainAutoreleasedReturnValue(v409);
        v411 = _objc_msgSend(
                 &OBJC_CLASS___NSDictionary,
                 "dictionaryWithObjectsAndKeys:",
                 isAppRunning,
                 CFSTR("bookmd5"),
                 lastTopicID,
                 CFSTR("topicid"),
                 0LL);
        v412 = objc_retainAutoreleasedReturnValue(v411);
        _objc_msgSend(v410, "delayOpenBook:", v412);// ⬅️⬅️⬅️⬅️⬅️
        _objc_release(v412);
        _objc_release(v410);
        v394 = book_v495___hasUpgraded;
        v391 = UIAlertView;
      }
"""
    
    let result2 =
"""
      isAppRunning = lastBookMD5;
      if (lastBookMD5
        && (v408 = _objc_msgSend(isAppRunning, "isEqualToString:", &stru_101187420), bookPath_v494___NSObject)
        && !v408 )
      {                                         // if (lastBookMD5 && lastBook && ![lastBookMD5 isEqualToString:@""])
        v409 = _objc_msgSend(self_v496, "rootController");
        v410 = objc_retainAutoreleasedReturnValue(v409);
        v411 = _objc_msgSend(&OBJC_CLASS___NSDictionary, "dictionaryWithObjectsAndKeys:", isAppRunning, CFSTR("bookmd5"), lastTopicID, CFSTR("topicid"), 0LL);







        v412 = objc_retainAutoreleasedReturnValue(v411);
        _objc_msgSend(v410, "delayOpenBook:", v412);// ⬅️⬅️⬅️⬅️⬅️
        _objc_release(v412);
        _objc_release(v410);
        v394 = book_v495___hasUpgraded;
        v391 = UIAlertView;
      }
"""
    if input2.fixBR() != result2 { fatalError() }
}

func test_String_findRightParen() {
    let input = """
_objc_msgSend())
()_objc_msgSend())
_objc_msgSend((789)))
"""
    let ouput = [14, 16, 19]
    let a = input.components(separatedBy: "\n")
    let result = a.map { (string) -> Int in
        guard let result = string.findRightParen("_objc_msgSend(") else { fatalError() }
        return result
    }
    if ouput != result {
        print("Error: \(result)")
        fatalError()
    }
//    a.map {
//        guard let result = $0.findRightParen("_objc_msgSend(") else { fatalError() }
//        return result
//    }
}

func test_String_fix_objc_msgSend() {
    let input =
"""
      v329 = _objc_msgSend(&OBJC_CLASS___NSBundle, "mainBundle");
      v330 = objc_retainAutoreleasedReturnValue(v329);
      lastTopicID = v330;
      v331 = (_objc_msgSend)(v330, "localizedStringForKey:value:table:", CFSTR("BookFileCrashAlertTitle"), &stru_101187420, 0LL);
      title = objc_retainAutoreleasedReturnValue(v331);// ⬅️⬅️⬅️⬅️⬅️
      v332 = (_objc_msgSend)(&OBJC_CLASS___NSBundle, "mainBundle");
      v333 = objc_retainAutoreleasedReturnValue(v332);
      v482 = v333;
      v334 = (_objc_msgSend)(v333, "localizedStringForKey:value:table:", CFSTR("BookFileCrashAlertMsg"), &stru_101187420, 0LL);

  if ( _objc_msgSend(g_globalAppDelegate, "appStoreVersion") )
"""
    let result =
"""
      v329 = [&OBJC_CLASS___NSBundle, "mainBundle"];
      v330 = objc_retainAutoreleasedReturnValue(v329);
      lastTopicID = v330;
      v331 = [v330, "localizedStringForKey:value:table:", CFSTR("BookFileCrashAlertTitle"), &stru_101187420, 0LL];
      title = objc_retainAutoreleasedReturnValue(v331);// ⬅️⬅️⬅️⬅️⬅️
      v332 = [&OBJC_CLASS___NSBundle, "mainBundle"];
      v333 = objc_retainAutoreleasedReturnValue(v332);
      v482 = v333;
      v334 = [v333, "localizedStringForKey:value:table:", CFSTR("BookFileCrashAlertMsg"), &stru_101187420, 0LL];

  if ( [g_globalAppDelegate, "appStoreVersion"] )
"""
    let a = input.components(separatedBy: "\n")
        .map {
            $0.fix_objc_msgSend()
        }
        .reduce(into: "") { (result, string) in
            result = result + string + "\n"
        }.dropLast()
    if a != result {
        let _ = a.components(separatedBy: "\n").map { print($0) }
        fatalError()
    }
}
